﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace RequestDemo
{
    public class Request
    {

        /// <summary>
        /// 服务器地址
        /// </summary>
        const String SERVER_URL = "https://10.12.0.87/";
        /// <summary>
        /// 证书路径
        /// </summary>
        const String CERT_PATH = @"F:\\Workplace\\openssl\\ca\\qfhssl\\lzsrkjkxxpt_client.p12";
        /// <summary>
        /// 证书密码
        /// </summary>
        const String CERT_PWD = "e3b3Y6YD7YjqAAaP";


        private static Request request = null;
        // 定义一个标识确保线程同步
        private static readonly object locker = new object();

        private string token;

        private Request()
        {
            getToken("admin", "admin");
        }

        public static Request GetInstance()
        {
            if (request == null)
            {
                lock (locker)
                {
                    if (request == null)
                    {
                        request = new Request();
                    }
                }
            }
            return request;
        }

        public ResponseBase dicUpLoad(String folderName, String dicDesc, String orgValue)
        {
            String url = SERVER_URL + "dataInterface/dicUpload?folderName={0}&dicDesc={1}&orgValue={2}&token={3}";
            String reqUrl = String.Format(url, folderName, dicDesc, orgValue, token);
            String res = "";
            try
            {
                res = requestSSL(reqUrl, CERT_PATH, CERT_PWD);
                ResponseBase response = JsonConvert.DeserializeObject<ResponseBase>(res);
                if (response.code.Equals(ResponseCode.RESPONSE_TOKEN_ERROR_CODE))
                {
                    return dicUpLoad(folderName, dicDesc, orgValue);
                }
                else
                {
                    return response;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("请求返回：" + res);
                Console.WriteLine(ex.Message);
                return null;
            }
        }
        public ResponseBase dataUpload(String businessName, String dataJson)
        {
            String url = SERVER_URL + "dataInterface/dataUpload?token={0}&businessName={1}&dataJson={2}";
            String reqUrl = String.Format(url, token, businessName, dataJson);
            String res = "";
            try
            {
                res = requestSSL(reqUrl, CERT_PATH, CERT_PWD);
                ResponseBase response = JsonConvert.DeserializeObject<ResponseBase>(res);
                if (response.code.Equals(ResponseCode.RESPONSE_TOKEN_ERROR_CODE))
                {
                    return dataUpload(businessName, dataJson);
                }
                else
                {
                    return response;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("请求返回：" + res);
                Console.WriteLine(ex.Message);
                return null;
            }
        }

        private void getToken(String user, String pwd)
        {
            String url = SERVER_URL + "interface/login?account={0}&password={1}";
            String reqUrl = String.Format(url, user, pwd);
            String res = "";
            try
            {
                res = this.requestSSL(reqUrl, CERT_PATH, CERT_PWD);
                ResponseToken response = JsonConvert.DeserializeObject<ResponseToken>(res);
                if (response.code.Equals(ResponseCode.RESPONSE_SUCCESS_CODE))
                {
                    this.token = response.token;
                }
                else
                {
                    Console.WriteLine(res);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("请求返回：" + res);
                Console.WriteLine(ex.Message);
            }
        }


        private string requestSSL(string url, string certPath, string certPwd)
        {
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
            X509Certificate2 cer = new X509Certificate2(certPath, certPwd,
                X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);

            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
            request.ClientCertificates.Add(cer);
            request.Method = "GET";
            request.ContentType = "application/x-www-form-urlencoded";

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            string result;
            using (StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
            {
                result = sr.ReadToEnd();
            }
            return result;
        }
        private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            return true;
        }
    }
}
